﻿using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace GreenXi.Help.UI
{
    public class PaggingControl : Control
    {
        // Using a DependencyProperty as the backing store for TotalPages.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TotalPagesProperty =
            DependencyProperty.Register("TotalPages", typeof(uint), typeof(PaggingControl),
                                        new PropertyMetadata(1u, TotalPagesPropertyChangeCallback));

        // Using a DependencyProperty as the backing store for CurrentPage.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentPageProperty =
            DependencyProperty.Register("CurrentPage", typeof(uint), typeof(PaggingControl),
                                        new PropertyMetadata(1u, CurrentPagePropertyChangeCallback));

        // Using a DependencyProperty as the backing store for PageSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PageSizeProperty =
            DependencyProperty.Register("PageSize", typeof(uint), typeof(PaggingControl),
                                        new PropertyMetadata(10u, PageSizePropertyChangecallback));

        // Using a DependencyProperty as the backing store for PageSizeList.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PageSizeListProperty =
            DependencyProperty.Register("PageSizeList", typeof(ObservableCollection<uint>), typeof(PaggingControl),
                                        new PropertyMetadata(new ObservableCollection<uint> { 10u, 20u, 50u, 100u }));

        // Using a DependencyProperty as the backing store for ItemsCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsCountProperty =
            DependencyProperty.Register("ItemsCount", typeof(uint), typeof(PaggingControl),
                                        new PropertyMetadata(1u, ItemsCountPropertyChangeCallback));

        // Using a DependencyProperty as the backing store for PageRefreshCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PageRefreshCommandProperty =
            DependencyProperty.Register("PageRefreshCommand", typeof(ICommand), typeof(PaggingControl),
                                        new PropertyMetadata(null));

        static PaggingControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PaggingControl),
                                                     new FrameworkPropertyMetadata(typeof(PaggingControl)));
        }

        public PaggingControl()
        {
            //第一次时候 刷新一下列表
            Loaded += delegate { RaisePageRefreshEvent(); };
        }

        /// <summary>总页数</summary>
        public uint TotalPages
        {
            get { return (uint)GetValue(TotalPagesProperty); }
            set { SetValue(TotalPagesProperty, value); }
        }

        /// <summary>当前页</summary>
        public uint CurrentPage
        {
            get { return (uint)GetValue(CurrentPageProperty); }
            set { SetValue(CurrentPageProperty, value); }
        }

        /// <summary>每页的大小</summary>
        public uint PageSize
        {
            get { return (uint)GetValue(PageSizeProperty); }
            set { SetValue(PageSizeProperty, value); }
        }

        /// <summary>每页大小列表，即页面大小选择框的数据源</summary>
        public ObservableCollection<uint> PageSizeList
        {
            get { return (ObservableCollection<uint>)GetValue(PageSizeListProperty); }
            set { SetValue(PageSizeListProperty, value); }
        }

        /// <summary>转到首页</summary>
        public ICommand FirstPageCmd
        {
            get
            {
                return new RelayCommand(() => { CurrentPage = 1; }
                                        , () => CurrentPage < TotalPages);
            }
        }

        /// <summary>上一页</summary>
        public ICommand PreviousPageCmd
        {
            get { return new RelayCommand(() => { CurrentPage -= 1; }, () => CurrentPage < TotalPages); }
        }

        /// <summary>下一页</summary>
        public ICommand NextPageCmd
        {
            get { return new RelayCommand(() => { CurrentPage += 1; }, () => CurrentPage < TotalPages); }
        }

        /// <summary>尾页</summary>
        public ICommand LastPageCmd
        {
            get { return new RelayCommand(() => { CurrentPage = TotalPages; }, () => CurrentPage != TotalPages); }
        }

        /// <summary>转到某一页</summary>
        public ICommand TurnToPageCmd
        {
            get { return new RelayCommand(RaisePageRefreshEvent); }
        }

        /// <summary>数据总大小</summary>
        public uint ItemsCount
        {
            get { return (uint)GetValue(ItemsCountProperty); }
            set { SetValue(ItemsCountProperty, value); }
        }

        /// <summary>参数 选择Tuple(uint, uint)代表页数 和页大小，即index和length</summary>
        public ICommand PageRefreshCommand
        {
            get { return (ICommand)GetValue(PageRefreshCommandProperty); }
            set { SetValue(PageRefreshCommandProperty, value); }
        }

        private static void TotalPagesPropertyChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as PaggingControl;
            if (ctrl != null)
            {
                if (ctrl.CurrentPage > ctrl.TotalPages)
                {
                    ctrl.CurrentPage = ctrl.TotalPages;
                }
                else if (ctrl.CurrentPage <= 1)
                {
                    ctrl.CurrentPage = 1;
                }
                ctrl.RaisePageRefreshEvent();
            }
        }


        private static void CurrentPagePropertyChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as PaggingControl;
            if (ctrl != null)
            {
                if (ctrl.CurrentPage > ctrl.TotalPages)
                {
                    ctrl.CurrentPage = ctrl.TotalPages;
                }
                else if (ctrl.CurrentPage <= 1)
                {
                    ctrl.CurrentPage = 1;
                }
                ctrl.RaisePageRefreshEvent();
            }
        }

        private static void PageSizePropertyChangecallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as PaggingControl;
            if (ctrl != null)
            {
                ctrl.TotalPages = ctrl.ItemsCount / ctrl.PageSize + (ctrl.ItemsCount % ctrl.PageSize == 0 ? 0 : 1u);
                ctrl.RaisePageRefreshEvent();
            }
        }

        private static void ItemsCountPropertyChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as PaggingControl;
            if (ctrl != null)
            {
                ctrl.TotalPages = ctrl.ItemsCount / ctrl.PageSize + (ctrl.ItemsCount % ctrl.PageSize == 0 ? 0 : 1u);
            }
        }

        private void RaisePageRefreshEvent()
        {
            if (PageRefreshCommand != null)
            {
                PageRefreshCommand.Execute(Tuple.Create(CurrentPage, PageSize));
            }
        }
    }
}
